package com.yungu.swift.system.sys.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yungu.swift.assets.driver.service.CarService;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.service.impl.BaseServiceImpl;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.system.sys.dao.SysCompanyMapper;
import com.yungu.swift.system.sys.model.dto.SysAccountCompanyDto;
import com.yungu.swift.system.sys.model.dto.SysCompanyDto;
import com.yungu.swift.system.sys.model.dto.SysRoleDto;
import com.yungu.swift.system.sys.model.dto.SysUserDto;
import com.yungu.swift.system.sys.model.param.AdminCompanyPageParam;
import com.yungu.swift.system.sys.model.vo.BusinessDetailVo;
import com.yungu.swift.system.sys.model.vo.BusinessVo;
import com.yungu.swift.system.sys.model.vo.CompanyDetailVo;
import com.yungu.swift.system.sys.model.vo.CompanyVo;
import com.yungu.swift.system.sys.service.SysAccountCompanyService;
import com.yungu.swift.system.sys.service.SysBusinessOrganizationService;
import com.yungu.swift.system.sys.service.SysCompanyService;
import com.yungu.swift.system.sys.service.SysUserService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.Md5Utils;
import com.yungu.swift.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * SysCompanyServiceImpl
 **/
@Service
public class SysCompanyServiceImpl extends BaseServiceImpl<SysCompanyDto> implements SysCompanyService {
    @Autowired
    private SysCompanyMapper sysCompanyMapper;
    @Autowired
    private SysBusinessOrganizationService sysBusinessOrganizationService;
    @Autowired
    private SysUserService sysUserService;
    @Reference
    private SysAccountCompanyService sysAccountCompanyService;
    @Reference
    private DriverService driverService;
    @Reference
    private CarService carService;
    @Reference
    private OrderFareService orderFareService;

    @Override
    protected IMapper<SysCompanyDto> getMapper() {
        return sysCompanyMapper;
    }


    @Override
    public ResponseData<PageVo<CompanyVo>> queryPageVo(AdminCompanyPageParam companyPageParam) {
        PageBounds pageBounds = new PageBounds(companyPageParam.getPageNum(), companyPageParam.getPageSize());
        PageList<CompanyVo> pageList = sysCompanyMapper.queryPageVo(BeanMap.create(companyPageParam), pageBounds);
        // 不显示小件业务
        pageList.forEach(companyVo -> {
            List<BusinessVo> businesses = companyVo.getBusinesses();
            if (CollectionUtils.isNotEmpty(businesses)) {
                List<BusinessVo> businessVos = businesses.stream().filter(businessVo -> businessVo.getType() !=
                        CommonConstant.BUSINESS_TYPE_PARCEL).collect(Collectors.toList());
                companyVo.setBusinesses(businessVos);
            }
        });
        PageVo<CompanyVo> pageVo = new PageVo(companyPageParam.getPageNum(), companyPageParam.getPageSize(),
                pageList.getPaginator().getTotalCount());
        pageVo.setItems(pageList);
        return ResponseData.buildSuccessResponse(pageVo);
    }

    /**
     * 详情
     *
     * @param companyUuid
     * @return
     * @author cuixiuyin
     */
    @Override
    public ResponseData<CompanyDetailVo> getDetail(String companyUuid, String appid) {
        CompanyDetailVo detailVo = new CompanyDetailVo();
        detailVo.setCompanyVo(sysCompanyMapper.selInfoAdmin(MapUtils.build("uuid", companyUuid)));
        detailVo.setCarCount(carService.getCarCount(null, null, companyUuid).getData());
        detailVo.setDriverCount(driverService.getCountAdmin(null, null, companyUuid).getData());
        Map<String, Object> build = MapUtils.build(4);
        build.put("companyUuid", companyUuid);
        build.put("appid", appid);
        detailVo.setTotalOrder(orderFareService.getIncome(build).getData());
        detailVo.setOrderCount(driverService.getOrderCount(null, null, companyUuid).getData());
        ResponseData<List<BusinessDetailVo>> responseData = this.sysBusinessOrganizationService.getBusinessDetail(companyUuid, null);
        if (responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())) {
            List<BusinessDetailVo> businesses = responseData.getData();
            // 跨城小件不作为单独业务
            detailVo.setBusinesses(businesses.stream().filter(businessDetailVo -> businessDetailVo.getType()
                    != CommonConstant.BUSINESS_TYPE_PARCEL).collect(Collectors.toList()));
        }
        return ResponseData.buildSuccessResponse(detailVo);
    }

    /**
     * 新增
     *
     * @param sysCompanyDto
     * @return
     * @author cuixiuyin
     */
    @Override
    @Transactional
    public ResponseData<Boolean> add(SysCompanyDto sysCompanyDto) {
        //检验，简称唯一
        ResponseData<SysUserDto> responseData = sysUserService.get(MapUtils.build("userAccount", sysCompanyDto.getShortName()));
        if (responseData.isSuccess() && responseData.getData() != null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "公司简称：" + sysCompanyDto.getShortName() + "已经被注册了");
        }
        //需要添加事务
        try {
            //新增公司
            sysCompanyDto.setUuid(StringUtils.buildUUID());
            sysCompanyDto.setStatus(CommonConstant.STATUS_OPENED.intValue());
            sysCompanyDto.setCreateOn(new Date());
            sysCompanyDto.setBalance(0d);
            sysCompanyMapper.add(sysCompanyDto);
            //同步新增公司账户
            SysAccountCompanyDto sysAccountCompanyDto = new SysAccountCompanyDto();
            sysAccountCompanyDto.setUuid(sysCompanyDto.getUuid());
            sysAccountCompanyDto.setAppid(sysCompanyDto.getAppid());
            sysAccountCompanyDto.setAccountName(sysCompanyDto.getFullName());
            sysAccountCompanyDto.setCashBalance(BigDecimal.ZERO);
            sysAccountCompanyDto.setCouponAccumulate(BigDecimal.ZERO);
            sysAccountCompanyDto.setRefundAccumulate(BigDecimal.ZERO);
            sysAccountCompanyDto.setRewardAccumulate(BigDecimal.ZERO);
            sysAccountCompanyDto.setCreateOn(new Date());
            sysAccountCompanyDto.setCreateBy(sysAccountCompanyDto.getCreateBy());
            sysAccountCompanyService.add(sysAccountCompanyDto);

            //新增公司管理员账号
            SysUserDto sysUserDto = new SysUserDto();
            sysUserDto.setUuid(StringUtils.buildUUID());
            sysUserDto.setUserName(sysCompanyDto.getShortName());
            sysUserDto.setUserAccount(sysCompanyDto.getShortName());
            sysUserDto.setPassword(Md5Utils.encode("Xdkj123456*"));
            sysUserDto.setFirstLogin(0);
            sysUserDto.setUserType(SysUserDto.USER_TYPE_PRIMARY);
            //默认公司管理员
            // todo 代理也有可能新建公司，这部分权限怎么设计？
            sysUserDto.setUserRole(SysRoleDto.DEFAULT_ROLE_COMPANY);
            sysUserDto.setAgentUuid(sysCompanyDto.getRegionalAgentUuid());
            sysUserDto.setCompanyUuid(sysCompanyDto.getUuid());
            sysUserDto.setStatus(SysUserDto.STATUS_NORMAL);
            sysUserDto.setAppid(sysCompanyDto.getAppid());
            sysUserDto.setResetPasswordDate(new Date());
            sysUserDto.setUserMobile(sysCompanyDto.getResponsibleMobile());
            sysUserDto.setCreateOn(new Date());
            sysUserService.add(sysUserDto);
            return ResponseData.buildSuccessResponse("新增成功", Boolean.TRUE);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "新增失败");
    }

    @Override
    @Transactional
    public ResponseData<Boolean> edit(SysCompanyDto updatedDto) {
        try {
            //检测公司简称是否有被修改，因为登陆账户采用简称登陆。
            SysCompanyDto sysCompanyDto = getMapper().list(MapUtils.build("uuid", updatedDto.getUuid())).get(0);
            //有对简称进行修改。
            if (sysCompanyDto != null && StringUtils.isNotEmpty(updatedDto.getShortName())
                    && !sysCompanyDto.getShortName().equals(updatedDto.getShortName())) {
                //查询对应的账户信息
                Map<String, Object> param = MapUtils.build(4);
                param.put("userAccount", sysCompanyDto.getShortName());
                param.put("userType", SysUserDto.USER_TYPE_PRIMARY);
                ResponseData<List<SysUserDto>> responseData = this.sysUserService.list(param);
                if (responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())) {
                    List<SysUserDto> listUsers = responseData.getData();
                    //账户异常
                    if (listUsers.size() > 1) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "公司账户异常，存在多个账户信息，请联系管理员。");
                    }
                    //判断是否有有账户名重复情况，有则不进行修改。
                    ResponseData<SysUserDto> resData = sysUserService.get(MapUtils.build("userAccount", updatedDto.getShortName()));
                    //已经存在账号名字一致的。
                    if (resData.isSuccess() && resData.getData() != null) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "公司简称：" + updatedDto.getShortName() + "已经被注册了");
                    }
                    //没有账户，新增
                    if (listUsers.size() == 0) {
                        SysUserDto sysUserDto = new SysUserDto();
                        sysUserDto.setUuid(StringUtils.buildUUID());
                        sysUserDto.setUserName(updatedDto.getShortName());
                        sysUserDto.setUserAccount(updatedDto.getShortName());
                        sysUserDto.setPassword(Md5Utils.encode(SysCompanyDto.INIT_PASSWORD));
                        sysUserDto.setUserType(SysUserDto.USER_TYPE_PRIMARY);
                        //默认公司管理员
                        sysUserDto.setUserRole(SysRoleDto.DEFAULT_ROLE_COMPANY);
                        sysUserDto.setAgentUuid(updatedDto.getRegionalAgentUuid());
                        sysUserDto.setCompanyUuid(updatedDto.getUuid());
                        sysUserDto.setStatus(SysUserDto.STATUS_NORMAL);
                        sysUserDto.setAppid(updatedDto.getAppid());
                        sysUserDto.setResetPasswordDate(new Date());
                        sysUserDto.setUserMobile(updatedDto.getResponsibleMobile());
                        sysUserDto.setCreateOn(new Date());
                        sysUserService.add(sysUserDto);
                    } else {
                        //修改
                        SysUserDto sysUserDto = listUsers.get(0);
                        sysUserDto.setUserName(updatedDto.getShortName());
                        sysUserDto.setUserAccount(updatedDto.getShortName());
                        sysUserDto.setUpdateOn(new Date());
                        sysUserDto.setUpdateBy(updatedDto.getUpdateBy());
                        sysUserService.edit(sysUserDto);
                    }

                }
            }
            return ResponseData.buildSuccessResponse("修改成功", sysCompanyMapper.edit(updatedDto) > 0);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "系统异常");
    }

    @Override
    public ResponseData<List<SysCompanyDto>> findCompanyByBusinessType(Map<String, Object> map) {
        return ResponseData.buildSuccessResponse(sysCompanyMapper.findCompanyByBusinessType(map));
    }

}